package com.cn.jinl.service;

import com.cn.jinl.api.IFileInfoService;
import com.cn.jinl.conf.Config;
import com.cn.jinl.dao.FileInfoMapper;
import com.cn.jinl.domain.FileInfo;
import com.cn.jinl.domain.FileInfoExample;
import com.cn.jinl.utils.CollectionsUtil;
import com.cn.jinl.utils.CommonUtil;
import com.cn.jinl.utils.Constants;
import com.cn.jinl.utils.QueryForm;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import sun.misc.BASE64Decoder;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

@Service
public class FileInfoServiceImpl implements IFileInfoService {

    @Autowired
    private FileInfoMapper fileInfoMapper;

    @Autowired
    private Config config;

    @Override
    public List<FileInfo> queryFileList(QueryForm queryForm) throws Exception {
        FileInfoExample example = new FileInfoExample();
        FileInfoExample.Criteria criteria = example.createCriteria();
        criteria.andStatusEqualTo(Constants.NORMAL_STATUS);
        if (StringUtils.isNotBlank(queryForm.getId())) {
            criteria.andIdEqualTo(queryForm.getId());
        }
        if (StringUtils.isNotBlank(queryForm.getRelateId())) {
            criteria.andRelateIdEqualTo(queryForm.getRelateId());
        }
        if (StringUtils.isNotBlank(queryForm.getFileName())) {
            criteria.andFileNameEqualTo(queryForm.getFileName());
        }
        if(StringUtils.isNotBlank(queryForm.getType())){
            criteria.andFileTypeEqualTo(queryForm.getType());
        }
        if(StringUtils.isNotBlank(queryForm.getCheck())){
            criteria.andFileCheckEqualTo(queryForm.getCheck());
        }
        if(CollectionsUtil.isNotEmpty(queryForm.getTypes())){
            criteria.andFileTypeIn(queryForm.getTypes());
        }
        if(CollectionsUtil.isNotEmpty(queryForm.getIds())){
            criteria.andIdIn(queryForm.getIds());
        }
        List<FileInfo> list = fileInfoMapper.selectByExample(example);
        return list;
    }



    @Override
    public List<FileInfo> queryFileListByRelateId(String relateId) throws Exception {
        FileInfoExample example = new FileInfoExample();
        example.createCriteria().andStatusEqualTo(Constants.NORMAL_STATUS).andRelateIdEqualTo(relateId);
        return fileInfoMapper.selectByExample(example);
    }

    @Override
    public String queryFileListById(String id) throws Exception {
        FileInfoExample example = new FileInfoExample();
        example.createCriteria().andIdEqualTo(id).andStatusEqualTo(Constants.NORMAL_STATUS);
        List<FileInfo> fileInfos = fileInfoMapper.selectByExample(example);
        if(null == fileInfos || fileInfos.size() !=1){
            return "";
        }
        return fileInfos.get(0).getFileUrl();
    }


    @Override
    public String addFile(FileInfo fileInfo) throws Exception {
        int count = 0;
        String id = CommonUtil.generateRandomNum("file-");
        String displayName = fileInfo.getFileName();
        fileInfo.setId(id);
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        String filePath = config.filePath + (StringUtils.isBlank(fileInfo.getSuffix()) ? "" : fileInfo.getSuffix() + File.separator);
        File file = new File(filePath);
        String fileName = CommonUtil.generateRandomNum("name-") + "-" + displayName;
        if (!file.exists() && !file.isDirectory()) {
            file.mkdirs();
        }
        try {
            String base64 = fileInfo.getFileBlob().split(",")[1];
            byte[] bytes = new BASE64Decoder().decodeBuffer(base64);
            file = new File(filePath + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
            file.setReadable(true);
            fileInfo.setFileSize(file.length()+ "");
            fileInfo.setFileName(fileName);
            fileInfo.setDisplayName(displayName);
            fileInfo.setFilePath(filePath + fileName);
            String url =  config.fileUrl + (StringUtils.isBlank(fileInfo.getSuffix()) ? "" : fileInfo.getSuffix() + "/");
            fileInfo.setFileUrl(url+fileName);
            count = fileInfoMapper.insertSelective(fileInfo);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return id;
    }

    @Override
    public String addFileWithBlob(String fileBlob) throws Exception {
        String url = "";
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        String filePath = config.filePath;
        File file = new File(filePath);
        String fileName = CommonUtil.generateRandomNum("name-");
        if (!file.exists() && !file.isDirectory()) {
            file.mkdirs();
        }
        try {
            String base64 = fileBlob.split(",")[1];
            byte[] bytes = new BASE64Decoder().decodeBuffer(base64);
            file = new File(filePath + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
            file.setReadable(true);
            url =  config.fileUrl + fileName;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return url;
    }

    @Override
    public String addFileUrl(FileInfo fileInfo) throws Exception {
        String id = CommonUtil.generateRandomNum("file-");
        fileInfo.setId(id);
        int count = fileInfoMapper.insertSelective(fileInfo);
        if(count < 0){
            throw new Exception("插入文件异常");
        }
        return id;
    }

    @Override
    public String batchAddFile(List<FileInfo> fileInfos) throws Exception {
        for(FileInfo fileInfo:fileInfos){
            String id = CommonUtil.generateRandomNum("file-");
            String displayName = fileInfo.getFileName();
            fileInfo.setId(id);
            if(StringUtils.isEmpty(fileInfo.getFileUrl())){
                BufferedOutputStream bos = null;
                FileOutputStream fos = null;
                String filePath = config.filePath + (StringUtils.isBlank(fileInfo.getSuffix()) ? "" : fileInfo.getSuffix() + File.separator);
                File file = new File(filePath);
                String fileName = CommonUtil.generateRandomNum("name-") + "-" + displayName;
                if (!file.exists() && !file.isDirectory()) {
                    file.mkdirs();
                }
                try {
                    String base64 = fileInfo.getFileBlob().split(",")[1];
                    byte[] bytes = new BASE64Decoder().decodeBuffer(base64);
                    file = new File(filePath + fileName);
                    fos = new FileOutputStream(file);
                    bos = new BufferedOutputStream(fos);
                    bos.write(bytes);
                    fileInfo.setFileSize(file.length()+ "");
                    fileInfo.setFileName(fileName);
                    fileInfo.setDisplayName(displayName);
                    fileInfo.setFilePath(filePath + fileName);
                    String url =  config.fileUrl + (StringUtils.isBlank(fileInfo.getSuffix()) ? "" : fileInfo.getSuffix() + "/");
                    fileInfo.setFileUrl(url+fileName);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (bos != null) {
                        try {
                            bos.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fos != null) {
                        try {
                            fos.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        int count = fileInfoMapper.batchInsertFiles(fileInfos);
        return CommonUtil.outStr(count);
    }

    @Override
    public String updateFile(FileInfo fileInfo) throws Exception {
        return null;
    }

    @Override
    public String updateBatchFile(List<FileInfo> fileInfos) throws Exception {
        if(CollectionUtils.isEmpty(fileInfos)){
            return "未查询到文件！";
        }
        String relateId = fileInfos.get(0).getRelateId();
        String result = this.deleteFileByRelateId(relateId);
        if(StringUtils.isNotEmpty(result)){
            return result;
        }
        result = this.batchAddFile(fileInfos);
        if(StringUtils.isNotEmpty(result)){
            throw new Exception(result);
        }
        return result;
    }

    @Override
    public String updateBatchFileWithOutFile(List<FileInfo> fileInfos) throws Exception {
        if(CollectionUtils.isEmpty(fileInfos)){
            return "未查询到文件！";
        }
        String relateId = fileInfos.get(0).getRelateId();
        String result = this.deleteFileByRelateId(relateId);
        if(StringUtils.isNotEmpty(result)){
            return result;
        }
        List<String> ids = Lists.newArrayList();
        for(FileInfo fileInfo:fileInfos){
            ids.add(fileInfo.getId());
        }
        FileInfo update = new FileInfo();
        update.setRelateId(relateId);
        FileInfoExample example = new FileInfoExample();
        example.createCriteria().andIdIn(ids);
        int count = fileInfoMapper.updateByExampleSelective(update,example);
        if(count < 0){
            throw new Exception("删除文件报错");
        }
        return CommonUtil.outStr(count);
    }

    @Override
    public String updateFileCheckStatus(List<FileInfo> fileInfos) throws Exception {
        if(CollectionsUtil.isEmpty(fileInfos)){
            throw new Exception("fileInfos is not null");
        }
        int count = fileInfoMapper.batchUpdateFileCheckStatus(fileInfos);
        return CommonUtil.outStr(count);
    }

    @Override
    public String deleteFileByIds(QueryForm queryForm) throws Exception {
        List<String> ids = queryForm.getIds();
        if (CollectionsUtil.isEmpty(ids)) {
            throw new Exception("deleteSetFileByIds ids empty!");
        }
        int count = 0;
        List<FileInfo> list = this.queryFileList(queryForm);
        if (CollectionsUtil.isNotEmpty(list)) {
            FileInfo setFile = new FileInfo();
            setFile.setStatus(Constants.DEL_STATUS);
            FileInfoExample example = new FileInfoExample();
            example.createCriteria().andIdIn(ids).andStatusEqualTo(Constants.NORMAL_STATUS);
            count = fileInfoMapper.updateByExampleSelective(setFile, example);
            if(count > 0){
                for(FileInfo file:list){
                    this.deleteFile(file.getFilePath());
                }
            }
        }

        return CommonUtil.outStr(count);
    }

    @Override
    public String deleteFileByIds(List<FileInfo> fileInfos) throws Exception {
        QueryForm queryForm = new QueryForm();
        List<String> ids = Lists.newArrayList();
        for(FileInfo fileInfo : fileInfos){
            ids.add(fileInfo.getId());
        }
        queryForm.setIds(ids);
        return deleteFileByIds(queryForm);
    }

    @Override
    public String deleteFileByRelateId(String relateId) throws Exception {
        int count = 0;
        QueryForm queryForm = new QueryForm();
        queryForm.setRelateId(relateId);
        List<FileInfo> list = this.queryFileList(queryForm);
        if (CollectionsUtil.isNotEmpty(list)) {
            FileInfoExample example = new FileInfoExample();
            FileInfo setFile = new FileInfo();
            setFile.setStatus(Constants.DEL_STATUS);
            example.createCriteria().andRelateIdEqualTo(relateId);
            count = fileInfoMapper.updateByExampleSelective(setFile, example);
            if(count > 0){
                for(FileInfo file:list){
                    this.deleteFile(file.getFilePath());
                }
            }
        }

        return CommonUtil.outStr(count);
    }

    @Override
    public String deleteFileByType(String type) throws Exception {
        if(StringUtils.isEmpty(type)){
            return "缺少参数";
        }
        FileInfoExample example = new FileInfoExample();
        FileInfo setFile = new FileInfo();
        setFile.setStatus(Constants.DEL_STATUS);
        example.createCriteria().andFileTypeEqualTo(type);
        int count = fileInfoMapper.updateByExampleSelective(setFile, example);
        if(count == 0){
            return "";
        }
        return  CommonUtil.outStr(count);
    }

    @Override
    public String getAppFileImagePath() throws Exception {
        FileInfoExample example = new FileInfoExample();
        example.createCriteria().andFileTypeEqualTo("9").andStatusEqualTo(Constants.NORMAL_STATUS);
        List<FileInfo> fileInfos = fileInfoMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(fileInfos)){
            return "";
        }
        return fileInfos.get(0).getFileUrl();
    }

    @Override
    public List<FileInfo> selectFileByRelateId(QueryForm queryForm) throws Exception {
        List<FileInfo> list = fileInfoMapper.selectFileByRelateId(queryForm);
        return list;
    }

    @Override
    public String addFileByBcsm(FileInfo fileInfo) throws Exception {
        int count = 0;
        String id = CommonUtil.generateRandomNum("file-");
        String displayName = fileInfo.getFileName();
        fileInfo.setId(id);
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        String filePath = config.filePath + (StringUtils.isBlank(fileInfo.getSuffix()) ? "" : fileInfo.getSuffix() + File.separator);
        File file = new File(filePath);
        String fileName = displayName;
        if (!file.exists() && !file.isDirectory()) {
            file.mkdirs();
        }
        try {
            String base64 = fileInfo.getFileBlob().split(",")[1];
            byte[] bytes = new BASE64Decoder().decodeBuffer(base64);
            file = new File(filePath + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
            file.setReadable(true);
            fileInfo.setFileSize(file.length()+ "");
            fileInfo.setFileName(fileName);
            fileInfo.setDisplayName(displayName);
            fileInfo.setFilePath(filePath + fileName);
            String url =  config.fileUrl + (StringUtils.isBlank(fileInfo.getSuffix()) ? "" : fileInfo.getSuffix() + "/");
            fileInfo.setFileUrl(url+fileName);
            count = fileInfoMapper.insertSelective(fileInfo);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return id;
    }

    private void deleteFile(String filePath) {
//        File file = new File(filePath);
//        if (file.exists()) {
//            file.delete();
//        }
    }
}
